/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.rcs.adslmonitor;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;
import javax.swing.JPanel;

/**
 *
 * @author pablo
 */
public class StatusHistoryPanel extends JPanel implements ADSLStatusListener {

  private List<Double> upStream = new ArrayList<Double>();
  private List<Double> attainableUpRate = new ArrayList<Double>();
  private List<Double> attenuationUpStream = new ArrayList<Double>();
  private List<Double> snrMarginUpStream = new ArrayList<Double>();
  private List<Double> downStream = new ArrayList<Double>();
  private List<Double> attainableDownRate = new ArrayList<Double>();
  private List<Double> attenuationDownStream = new ArrayList<Double>();
  private List<Double> snrMarginDownStream = new ArrayList<Double>();
  private int xDelta = 1;

  public StatusHistoryPanel() {
    setBackground(Color.black);
  }

  public void statusChanged(EventObject evt) {
    try {
      ADSLStatus status = (ADSLStatus) evt.getSource();

      snrMarginUpStream.add(status.getAsDouble(ADSLStatus.KEYS.SNR_MARGIN_UP_STREAM));
      snrMarginDownStream.add(status.getAsDouble(ADSLStatus.KEYS.SNR_MARGIN_DOWN_STREAM));

      attenuationDownStream.add(status.getAsDouble(ADSLStatus.KEYS.ATTENUATION_DOWN_STREAM));
      attenuationUpStream.add(status.getAsDouble(ADSLStatus.KEYS.ATTENUATION_UP_STREAM));

      ++xDelta;

      repaint();
    } catch (Throwable th) {
      th.printStackTrace();
    }
  }

  @Override
  public void paint(Graphics g) {
    super.paint(g);

    try {
      Dimension dim = getSize();

      double max = calcMax(dim.width, snrMarginUpStream, snrMarginDownStream, attenuationUpStream, attenuationDownStream);
      double units = 10.0;

      if (0 == max || max > dim.height)
        max = dim.height;

      double scale = dim.height / (((int) (max / units)) * units + units);

      drawAxis(g, dim, units, max, scale);

      drawListValues(g, dim, scale, snrMarginUpStream, snrMarginDownStream, Color.yellow);
      drawListValues(g, dim, scale, attenuationUpStream, attenuationDownStream, Color.green);
    } catch (Throwable th) {
      th.printStackTrace();
    }
  }

  private double calcMax(List<Double> data, int maxSize) {
    double result = 0;

    while (maxSize < data.size())
      data.remove(0);

    for (double current : data)
      if (result < current)
        result = current;

    return result;
  }

  private double calcMax(int maxItems, List<Double>... data) {
    double max = 0;

    for (List<Double> currentData : data) {
      double currentMax = calcMax(currentData, maxItems);
      max = Math.max(max, currentMax);
    }

    return max;
  }

  private void drawListValues(Graphics g, Dimension dim, List<Double> data, Color color, double scale) {
    int x = dim.width;

    g.setColor(color);

    for (int i = data.size() - 1; i > 0; --i) {
      int y1 = (int) (scale * data.get(i));
      int y2 = (int) (scale * data.get(i - 1));

      g.drawLine(x, dim.height - y1, x - 1, dim.height - y2);
      --x;
    }
  }

  private void drawAxis(Graphics g, Dimension dim, double units, double max, double scale) {
    g.setColor(Color.gray.darker());

    // dibujamos los ejes Y
    for (double yd = units; yd < max; yd += units) {
      int y = (int) (scale * yd);

      g.drawLine(0, y, dim.width, y);
    }

    xDelta = (xDelta % (int) units);

    // dibujamos los ejes X
    for (int xd = dim.width - xDelta; xd >= 0; xd -= units)
      g.drawLine(xd, 0, xd, dim.height);
  }

  private void drawListValues(Graphics g, Dimension dim, double scale, List<Double> up, List<Double> down, Color baseColor) {
    drawListValues(g, dim, up, baseColor.darker(), scale);
    drawListValues(g, dim, down, baseColor.brighter(), scale);
  }
}
